// CopyRight (c), 2011, Jorge J. Sainz, 

var Red_A  = '10.0.0.0/255.0.0.0';
var Red_B  = '172.16.0.0/255.240.0.0';
var Red_C  = '192.168.0.0/255.255.0.0';

function IPClase(ip) {
   	var octip = new Array();

   	var minrnga = new Array(1, 0, 0, 0);
   	var maxrnga = new Array(126, 255, 255, 254);
   	var minrngb = new Array(128, 1, 0, 0);
   	var maxrngb = new Array(191, 254, 255, 254);
   	var minrngc = new Array(192, 0, 1, 0);
   	var maxrngc = new Array(223, 255, 254, 254);
	
    try {
		result = 'N';
        octip = ip.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.');

        if ((octip[0] >= minrnga[0]) && (octip[0] <= maxrnga[0]) &&
            (octip[1] >= minrnga[1]) && (octip[1] <= maxrnga[1]) &&
            (octip[2] >= minrnga[2]) && (octip[2] <= maxrnga[2]) &&
            (octip[3] >= minrnga[3]) && (octip[3] <= maxrnga[3])) {

            return 'A';
        }
        else result = result;

        if ((octip[0] >= minrngb[0]) && (octip[0] <= maxrngb[0]) &&
            (octip[1] >= minrngb[1]) && (octip[1] <= maxrngb[1]) &&
            (octip[2] >= minrngb[2]) && (octip[2] <= maxrngb[2]) &&
            (octip[3] >= minrngb[3]) && (octip[3] <= maxrngb[3])) {

           return 'B';
        }
        else result = result;

        if (octip[2] > 0) {
            if ((octip[0] >= minrngc[0]) && (octip[0] <= maxrngc[0]) &&
                (octip[1] >= minrngc[1]) && (octip[1] <= maxrngc[1]) &&
                (octip[2] >= minrngc[2]) && (octip[2] <= maxrngc[2]) &&
                (octip[3] >= minrngc[3]) && (octip[3] <= maxrngc[3])) {

                return 'C';
            }
            else
                result = result
		}
        else
            if ((octip[0] >= minrngc[0]) && (octip[0] <= maxrngc[0]) &&
                (octip[1] >= minrngc[1]) && (octip[1] <= maxrngc[1]) &&
                (octip[3] >= minrngc[3]) && (octip[3] <= maxrngc[3])) {

                return 'C';
            }
            else
                result = result;
    } 
	catch (e) {
        result = 'N';
    }
	return result;
}

function IPCheck(ip, netm) {
   var octip = new Array()
   var octma = new Array()
   try {
        if (IPClase(ip) == 'N') return false;

		octip = ip.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.');
		octma = netm.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.');

        for (i = 0; i<=3; i++) {
            if ((octma[i] != 0) && (octma[i] != 255)) {
                if ((octip[i] & octma[i]) == octip[i]) return false;
                if (octip[i] == ((octip[i] & octma[i]) + (255 - octma[i]))) return false;
			}
   		}

        result = true;
   	}
    catch (e) {
        result = false;
	}
	return result;
}

function CNetwork(ip, mask) {
	var ipad_oct = new Array()
    var netw_oct = new Array()
    var mask_oct = new Array()
	
    try {
        if (IPClase(ip) == 'N') return 'none';
	
		ipad_oct = ip.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.');
		mask_oct = mask.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.');

        netw_oct.push(ipad_oct[0] & mask_oct[0]);
        netw_oct.push(ipad_oct[1] & mask_oct[1]);
        netw_oct.push(ipad_oct[2] & mask_oct[2]);
        netw_oct.push(ipad_oct[3] & mask_oct[3]);

        return netw_oct.join('.')

	}
	catch (e) {
        return 'none';
	}
}

function CBroadcast(ip, netw, mask) {
	var ipad_oct = new Array()
    var netw_oct = new Array()
    var mask_oct = new Array()
    var bcat_oct = new Array()
    var ok = false;

	try {
		if (IPClase(ip) == 'N') return 'none';
	
		ipad_oct = ip.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.');
		netw_oct = netw.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.');
		mask_oct = mask.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.');

        ok = (((ipad_oct[0] & mask_oct[0]) == netw_oct[0]) &&
              ((ipad_oct[1] & mask_oct[1]) == netw_oct[1]) &&
              ((ipad_oct[2] & mask_oct[2]) == netw_oct[2]) &&
              ((ipad_oct[3] & mask_oct[3]) == netw_oct[3]));

        if (ok) {
            bcat_oct[0] = parseInt(netw_oct[0]) + (255 - parseInt(mask_oct[0]))
            bcat_oct[1] = parseInt(netw_oct[1]) + (255 - parseInt(mask_oct[1]))
            bcat_oct[2] = parseInt(netw_oct[2]) + (255 - parseInt(mask_oct[2]))
            bcat_oct[3] = parseInt(netw_oct[3]) + (255 - parseInt(mask_oct[3]))
		}
        else return 'none';

        return bcat_oct.join('.');
	}
	catch (e) {
        return 'none';
	}
}

function MaskToInt(m) {
    var maskbin = ''
    var resint = 0
    var i = 0
	var oct = 0

    try {
		try {
			(m.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.') != 4)
		}
		catch (e) { return -1 }
			
        resint = 0;
        for (i= 0; i < 4; i++) {
			oct = parseInt(m.split('.')[i])
			if ((oct > 255) || (oct < 0)) return -1
			maskbin = Dec2Base(oct, 2);
			try {
				resint += (maskbin.match(new RegExp('1','g')).length);
			} catch (e) {}
		}
        return ((resint >= 0) && (resint <= 32)) ? resint : -1
	}
	catch (e) {
        return -1;
	}
}

function IntToMask(n){
    var otm = new Array()
	var tmp = 0
    maskbin = ''
    i = 0;

    try {
		if ((n > 32) || (n < 0)) return 'x.x.x.x';
		maskbin = replicate('1', n) + replicate('0', 32 - n);
        i = 0;
        do {
            otm.push(Base2Dec(maskbin.substr(i, 8), 2));
            i += 8;
		}
        while (i < 31);
		
        return otm.join('.')
	}
	catch (e) {
        return 'x.x.x.x';
	}
}

function Num2Ip(ipnumber) {
    var oct_v = new Array(0,0,0,0)
    var i = 0
    var ipt 
	var pp

    try {
        ipt = ipnumber;
        for (i=3; i >= 0; i--) {
            oct_v[3 - i] = Math.floor(ipt / Math.pow(256,i));
            ipt = ((ipt / Math.pow(256, i)) - oct_v[3 - i]) * Math.pow(256, i);
		}
        return oct_v.join('.')
	}
	catch (e) {
        return 'x.x.x.x';
	}
}

function Ip2Num(ipstr) {
   	var i = 0
   	var octp = new Array()
   	var result = 0

	try {
		octp = ipstr.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.');
        for (i = 0; i <= 3; i++) 
           result += (parseInt(octp[i]) * Math.pow(256,(3 - i)));
        
        return result;
    }
	catch (e) {
        return -1;
    }
}

// El numero de ip contenida en una mascara que 
// devuelve esta funcion es menos 2 (ip red y broadcast)
function NumbersOfIP(mask) {
	var b = -1;

    try {
		b = MaskToInt(mask)
        return  (b == 32) ? 1 : ((b != -1) ? Math.floor(Math.pow(2, (32 - b))) - 2 : -1);
	}
	catch (e) {
        return 0;
	}
}

function IPIntranet(ipstr) {
	var ipoct = new Array()

    try {
		ipoct = ipstr.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)[0].split('.');
        switch (parseInt(ipoct[0])) {
            case  10 : return (CBroadcast(ipstr, 
											Red_A.substr(0, Red_A.indexOf('/', 0)),
											Red_A.substr(Red_A.indexOf('/', 0) + 1, Red_A.length)
										   ) != 'none');
            case 127 : return ((parseInt(ipoct[1]) == 0) && 
			    				 (parseInt(ipoct[2]) == 0) && 
								 (parseInt(ipoct[3]) == 1));
            case 172 : if (parseInt(ipoct[1]) == 16)
                    		return (CBroadcast(ipstr, 
											    Red_B.substr(0, Red_B.indexOf('/', 0)), 
												Red_B.substr(Red_B.indexOf('/', 0) + 1, Red_B.length)
												) != 'none');
            case 192 : if (parseInt(ipoct[1]) == 168) 
                    		return (CBroadcast(ipstr, 
											    Red_C.substr(0, Red_C.indexOf('/', 0)), 
												Red_C.substr(Red_C.indexOf('/', 0) + 1, Red_C.length)
												) != 'none');
        }
    }
	catch (e) { }
	return false;
}

